import {DeleteBuilder} from './DeleteBuilder';
import {InsertBuilder} from './InsertBuilder';
import {SelectBuilder} from './SelectBuilder';
import {UpdateBuilder} from './UpdateBuilder';
import {Entity, FieldSelection, SqlBuilderExtensions, TableEntityMapping, UpdateFields} from "./types";
import {SqlExecutor} from "../execution";
import {Database} from 'better-sqlite3';

/**
 * SQL构建器
 * 统一管理所有SQL操作（增删改查）
 */
export class SqlBuilder<T> {
  /** 表名 */
  private tableName: string;

  /** 表别名 */
  private tableAlias?: string;

  /** 实体映射信息 */
  private entityMapping?: TableEntityMapping;

  /** SQL构建器扩展 */
  private extensions?: SqlBuilderExtensions;

  /** SQL执行器 */
  private executor?: SqlExecutor;

  /**
   * 构造函数
   * @param tableName 表名
   * @param tableAlias 表别名（可选）
   * @param entityMapping 实体映射信息（可选）
   * @param extensions SQL构建器扩展（可选）
   * @param executor SQL执行器（可选）
   */
  constructor(
    tableName: string,
    tableAlias?: string,
    entityMapping?: TableEntityMapping,
    extensions?: SqlBuilderExtensions,
    executor?: SqlExecutor
  ) {
    this.tableName = tableName;
    this.tableAlias = tableAlias;
    this.entityMapping = entityMapping;
    this.extensions = extensions;
    this.executor = executor;
  }

  /**
   * 创建SQL构建器实例
   * @param tableName 表名
   * @param tableAlias 表别名（可选）
   * @param entityMapping 实体映射信息（可选）
   * @param extensions SQL构建器扩展（可选）
   * @param executor SQL执行器（可选）
   */
  public static create<E>(
    tableName: string,
    tableAlias?: string,
    entityMapping?: TableEntityMapping,
    extensions?: SqlBuilderExtensions,
    executor?: SqlExecutor
  ): SqlBuilder<E> {
    return new SqlBuilder<E>(tableName, tableAlias, entityMapping, extensions, executor);
  }

  /**
   * 为指定实体类型创建SQL构建器
   * @param tableName 表名
   * @param tableAlias 表别名（可选）
   * @param entityMapping 实体映射信息（可选）
   * @param extensions SQL构建器扩展（可选）
   * @param executor SQL执行器（可选）
   */
  public static forEntity<E extends Entity>(
    tableName: string,
    tableAlias?: string,
    entityMapping?: TableEntityMapping,
    extensions?: SqlBuilderExtensions,
    executor?: SqlExecutor
  ): SqlBuilder<E> {
    return new SqlBuilder<E>(tableName, tableAlias, entityMapping, extensions, executor);
  }

  /**
   * 设置表别名
   * @param alias 别名
   */
  public as(alias: string): SqlBuilder<T> {
    const clone = new SqlBuilder<T>(
      this.tableName,
      alias,
      this.entityMapping,
      this.extensions,
      this.executor
    );
    return clone;
  }

  /**
   * 设置db数据库，相当于通过数据库添加执行器
   * @param db 数据库
   * @returns 当前构建器实例
   */
  public setDB(db: Database): SqlBuilder<T> {
    this.executor = new SqlExecutor(db);
    return this;
  }

  /**
   * 设置SQL执行器
   * @param executor SQL执行器
   * @returns 当前构建器实例
   */
  public setExecutor(executor: SqlExecutor): SqlBuilder<T> {
    this.executor = executor;
    return this;
  }

  /**
   * 获取SQL执行器
   * @returns SQL执行器实例或undefined
   */
  public getExecutor(): SqlExecutor | undefined {
    return this.executor;
  }

  /**
   * 设置SQL构建器扩展
   * @param extensions SQL构建器扩展
   */
  public withExtensions(extensions: SqlBuilderExtensions): SqlBuilder<T> {
    const clone = new SqlBuilder<T>(
      this.tableName,
      this.tableAlias,
      this.entityMapping,
      extensions,
      this.executor
    );
    return clone;
  }

  /**
   * 设置实体映射
   * @param mapping 实体映射
   */
  public withMapping(mapping: TableEntityMapping): SqlBuilder<T> {
    const clone = new SqlBuilder<T>(
      this.tableName,
      this.tableAlias,
      mapping,
      this.extensions,
      this.executor
    );
    return clone;
  }

  /**
   * 创建查询构建器
   * @param fields 要查询的字段，不提供则选择所有字段(*)
   * @returns 选择构建器实例
   *
   * @example 选择所有字段
   * ```typescript
   * // SELECT * FROM users t
   * const query = userTable.select();
   * ```
   *
   * @example 选择特定字段
   * ```typescript
   * // SELECT t.id, t.name, t.email FROM users t
   * const query = userTable.select('id', 'name', 'email');
   * ```
   *
   * @example 链式使用
   * ```typescript
   * // SELECT t.id, t.name FROM users t WHERE t.status = 'active'
   * const query = userTable.select('id', 'name').where('status', '=', 'active');
   * ```
   */
  public select(...fields: FieldSelection<T>): SelectBuilder<T> {
    const builder = new SelectBuilder<T>(
      this.tableName,
      this.tableAlias,
      this.entityMapping,
      this.extensions
    );

    // 如果设置了执行器，传递给构建器
    if (this.executor) {
      builder.setExecutor(this.executor);
    }

    // 如果提供了字段参数，设置查询字段
    if (fields.length > 0) {
      builder.select(...fields);
    }

    return builder;
  }

  /**
   * 创建插入构建器
   * @param data 要插入的数据
   */
  public insert(data: Partial<T> | Partial<T>[]): InsertBuilder<T> {
    const builder = new InsertBuilder<T>(
      this.tableName,
      data,
      this.entityMapping,
      this.extensions
    );

    // 如果设置了执行器，传递给构建器
    if (this.executor) {
      builder.setExecutor(this.executor);
    }

    return builder;
  }

  /**
   * 创建更新构建器
   * @param fields 要更新的字段
   */
  public update(fields: UpdateFields<T>): UpdateBuilder<T> {
    const builder = new UpdateBuilder<T>(
      this.tableName,
      fields,
      this.entityMapping,
      this.extensions
    );

    // 如果设置了执行器，传递给构建器
    if (this.executor) {
      builder.setExecutor(this.executor);
    }

    return builder;
  }

  /**
   * 创建删除构建器
   */
  public delete(): DeleteBuilder<T> {
    const builder = new DeleteBuilder<T>(
      this.tableName,
      this.entityMapping,
      this.extensions
    );

    // 如果设置了执行器，传递给构建器
    if (this.executor) {
      builder.setExecutor(this.executor);
    }

    return builder;
  }
}
